package com.ly.mpayment.rest.recharge;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;

import com.alibaba.fastjson.JSON;
import com.ly.mpayment.core.util.*;
import com.ly.mpayment.persist.entity.*;
import com.ly.mpayment.persist.service.blacklist.IBlackListService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.ly.mpayment.core.secuity.MD5;
import com.ly.mpayment.persist.service.downrechargeflow.IDownRechargeFlowService;
import com.ly.mpayment.persist.service.downshopinfo.IDownShopInfoService;
import com.ly.mpayment.persist.service.downshopproduct.IDownShopProductService;
import com.ly.mpayment.persist.service.mobile.IMobileService;
import com.ly.mpayment.persist.service.provincialinformation.IProvincialInformationService;
import com.ly.mpayment.rest.AbsRest;

@Component
@Path("recharge")
public class RechargeRest extends AbsRest {

	Logger logger = Logger.getLogger(RechargeRest.class);

	public static BlockingQueue<DownRechargeFlow> orderQueue = new LinkedBlockingQueue<>();

	//map orderid ,errormsg
	//失败订单
	public static BlockingQueue<UpOrder> failtUpOrder = new LinkedBlockingQueue<>();

	/**
	 * 重复提交下游订单队列
	 */
	public static BlockingQueue<DownRechargeFlow> repeatUpOrder = new LinkedBlockingQueue<>();

	/**
	 * 成功上游订单
	 */
	//成功订单
	public static BlockingQueue<UpOrder> successUpOrder = new LinkedBlockingQueue<>();

	//压单队列
	public static BlockingQueue<UpOrder> pressUpOrder = new LinkedBlockingQueue<>();

	@Autowired
	IDownShopInfoService shopService;

	@Autowired
	IDownRechargeFlowService flowService;

	@Autowired
	IDownShopProductService productService;

	@Autowired
	IMobileService mobileService;

	@Autowired
	IProvincialInformationService proService;

	@Autowired
	IBlackListService blackListService;

	/**
	 * @param data
	 * @param request
	 * @return
	 */
	@Path("commit")
	@POST
	public String recharge(String data, @Context HttpServletRequest request) {
		logger.info("commit:"+data);
		return rechargeOrder(data,request,true);
	}

	public String rechargeOrder(String data,@Context HttpServletRequest request,boolean isIp){
		if (!StringUtils.isBlank(data)) {
			com.alibaba.fastjson.JSONObject json = com.alibaba.fastjson.JSONObject.parseObject(data);
			//查询产品是否正常删除或者禁用的不可以提单
			DownShopProduct downProduct = this.productService.findByNotUseUUId(json.getString("pid"),json.getString("uid"));
			if (downProduct == null) {
				return ResultMessage.getFailt(ResultMessage.productDownError);
			}
			DownShopInfo shop = shopService.findShopInfoForMaintenance(json.getString("uid"));
			if(shop != null && shop.getUser().getUserstatus() == Config.productStatus[3]){
				return ResultMessage.getFailt(ResultMessage.userCloseError);
			}
			if (shop != null ) {
				if(checkIp(shop.getDownshopip(), request,isIp) || shop.getUser().getUseruuid().equals(CookieRedis.get("useruuid"))){
					if(json.getString("sign").equals(getRechargeMd5(json, shop))){
						String result = chekcParameter(json);
						if (result != null) {
							return result;
						}
//						Mobile mobile = checkMobile(json.getString("phone").trim());
//						if(mobile == null){
//							return ResultMessage.getFailt(ResultMessage.phoneNumError);
//						}
						if(blackListService.findPhone(json.getString("phone")) != null){
							return ResultMessage.getFailt(ResultMessage.mobileError);
						}
						//检查失败号码不能超过多少笔
						if(flowService.findByPhoneCount(json.getString("phone")) > Integer.valueOf(CookieRedis.get("PhoneMax"))){
							return ResultMessage.getFailt(ResultMessage.mobileError);
						}
						//检查省份是否维护
						//SCDMA	中国移动
						//WCDMA	中国联通
						//CDMA	中国电信
						if(CookieRedis.get("dsable_province") != null && !CookieRedis.get("dsable_province").equals("0")){
							String provinces [] = CookieRedis.get("dsable_province").split(",");
							for(int i = 0 ; i < provinces.length; i ++){
								String pro = provinces[i].contains(Config.opearter[0]) ? Config.opearterName[0] :
											 provinces[i].contains(Config.opearter[1]) ? Config.opearterName[2] :
											 provinces[i].contains(Config.opearter[2]) ? Config.opearterName[1] : "";
//								if(mobile.getProvince().equals(provinces[i].split("-")[1]) && mobile.getServiceProvider().equals(pro)){
//									return ResultMessage.getFailt(ResultMessage.buscodeNotError);
//								}
							}
						}						//如果是全国则不检查运营商
//							if(CookieRedis.get("nationwide").equals(Config.onOff)){
//								boolean temp = true;
//								for(int i = 0 ;i < Config.opearterName.length;i++){
//									if(Config.opearterName[i].equals(mobile.getServiceProvider()) && downProduct.getOperators().getOperatorname().equals(mobile.getServiceProvider())){
//										temp = false;
//									}
//								}
//								if(temp){
//									return ResultMessage.getFailt(ResultMessage.rechargeNumOperatorError);
//								}
//							}
						//如果产品为全国 则不检查省份
						if(!downProduct.getProvincialInformation().getProvincename().equals(Config.proCity)){
							//检查充值号段与产品号段是否匹配
//							if(mobile != null && !mobile.getProvince().equals(downProduct.getProvincialInformation().getProvincename())){
//								return ResultMessage.getFailt(ResultMessage.provinceError);
//							}
						}
						//检查省份是否维护
//						if(mobile != null && downProduct.getProvincialInformation() != null && !StringUtils.isBlank(mobile.getProvince())
//								&& mobile.getProvince().equals(downProduct.getProvincialInformation().getProvincename())){
//							if(downProduct.getProvincialInformation().getProvincestatus().equals("0")){
//								return ResultMessage.getFailt(ResultMessage.provinceErrorweihu);
//							}
//						}

						//检查充值号段是否禁止提单，如果是则不能保存订单
//						if(mobile == null || mobile.getState() == Config.mobileState){
//							return ResultMessage.getFailt(ResultMessage.mobileError);
//						}
//						if(!StringUtils.isBlank(downProduct.getCityName()) && !mobile.getCity().equals(downProduct.getCityName())){
//							return ResultMessage.getFailt(ResultMessage.provinceError);
//						}
						final DownRechargeFlow flow = new DownRechargeFlow();
						Date date = DateUtils.getNowDate();
						flow.setCreatetime(date);

						flow.setDownreqid(json.getString("orderId"));
						flow.setUserFlow(new User(json.getString("uid")));
						flow.setRechargeamount(downProduct.getPrice());
						flow.setDowonphonenum(json.getString("phone"));
						flow.setOperators(downProduct.getOperators().getOperatoruid());
						flow.setDownnotificationaddress(json.getString("notify"));
						if(shop.getUser().getUserstatus() != Config.productStatus[1] || downProduct.getStatus() != Config.productStatus[1]){
							flow.setStatus(Config.status[9] );
							//缓存订单
						}else{
							flow.setStatus(Config.status[5] );
							//订单到达
						}
						flow.setOperatorname(downProduct.getOperators().getOperatorname());
						flow.setBusCode(downProduct.getBusinessType().getBusCode());
						flow.setProvince(downProduct.getProvincialInformation().getProvincename());
						flow.setCityName("");
						flow.setCallStatus(Config.callStatus[0]);
						//充值数量
						flow.setDownrechargenum(json.containsKey("number") ? Integer.valueOf(json.getString("number") ): 1);
						flow.setDownendtimesec(Config.status[3]);
						flow.setDownShopProduct(downProduct);
						flow.setDownreqnum(0);
						flow.setDiscount(downProduct.getDiscount());
						flow.setDiscountAmount(downProduct.getPrice().multiply(BigDecimal.valueOf(flow.getDownrechargenum())).multiply(downProduct.getDiscount()));
						//重复提交次数 产品默认为1
						flow.setDownreqnum(downProduct.getDownfailnum());
						flow.setStatusremark(json.containsKey("statusremark") ? json.getString("statusremark") : "");
						flow.setName(json.containsKey("name") ? json.getString("name") : "");
						flow.setSourceIp(json.containsKey("sourceIp") ? json.getString("sourceIp") : "");
						flow.setAreaName(json.containsKey("areaName") ? json.getString("areaName") : "");
						flow.setServer(json.containsKey("server") ? json.getString("server") : "");
						flow.setRechargeType(json.containsKey("rechargeType") ? json.getString("rechargeType") : "");
						//查询下游余额
						// 检查余额
						if(CookieRedis.get("checkbalance").equals(Config.onOff)){
							if (shop.getDownshopbalance().compareTo(flow.getDiscountAmount()) == -1) {
								return ResultMessage.getFailt(ResultMessage.shopAmountError);
							}
						}
						//检查授信额度 如果有授信额度则可以提交订单，如果没有直接返回约不足，如果授信额度满了，直接返回余额不足
						if(flow.getDiscountAmount().compareTo(shop.getDownshopbalance()) == 1
								&& ( flow.getDiscountAmount().compareTo(shop.getCredit()) == 1 )	){
							return ResultMessage.getFailt(ResultMessage.shopAmountError);
						}
						//检查余额消耗。如果余额小于0 则取反大于授信 就不能继续提单
						if(shop.getDownshopbalance().compareTo(BigDecimal.ZERO) == -1 && Math.abs(shop.getDownshopbalance().intValue())
								>= shop.getCredit().intValue()){
							return ResultMessage.getFailt(ResultMessage.shopAmountError);
						}
						try {
							final DownRechargeFlow flowfinal = flowService.addDownrechargeflow(flow, shop);
							if(flowfinal != null){
								if(shop.getUser().getUserstatus() == Config.productStatus[1] && downProduct.getStatus() == Config.productStatus[1]){
									orderQueue.add(flowfinal);
								}else{
									flow.setRemark("产品或者供货商未启用");
									this.flowService.updateDownrechargeflow(flowfinal);
									logger.info("recharge_缓存订单:"+flowfinal.getDowonphonenum());
								}

								final JSONObject out = new JSONObject();
								out.put("oid", flowfinal.getDownorderuuid());
								out.put("time", DateUtils.toLongDate(flowfinal.getCreatetime()));
								JSONObject jobOut = new JSONObject();
								jobOut.put("data",out);
								jobOut.put("code","1000");
								jobOut.put("message", "订单提交成功" );
								logger.info("returnOrder:"+flowfinal.getDowonphonenum()+","+out.toString()+","+jobOut.toJSONString());
								return jobOut.toJSONString();
							}else{
								logger.info("failt:"+flow.getDowonphonenum());
								return ResultMessage.getFailt(ResultMessage.systemErrorMessageQuery);
							}
						} catch (Exception e) {
							e.printStackTrace();
							logger.error(e.getMessage()+":"+ flow == null ? "flow" : flow.getDowonphonenum());
							return ResultMessage.getFailt(ResultMessage.systemErrorMessageQuery);
						}
					}else{
						logger.info("signError:"+data+","+DateUtils.getNowDateToString());
						return ResultMessage.getFailt(ResultMessage.signError);
					}
				}else{
					return ResultMessage.getFailt(ResultMessage.shopNotexistErrorIP);
				}
			}  else {
				return ResultMessage.getFailt(ResultMessage.shopNotexistErrorIP);
			}
		}
		return ResultMessage.getFailt(ResultMessage.shopParameterError);
	}

	public static void main(String[] args) {
		JSONObject jsonObject = JSONObject.parseObject("{\"areaName\":\"\",\"name\":\"Q币\",\"notify\":\"http://callback.eyueapi.com/CallBack/KuaiShou/Add\",\"number\":\"200\",\"orderId\":\"4177063584633301\",\"phone\":\"2098814381\",\"pid\":\"QB_QG_ZC_duoyu_1\",\"sourceIp\":\"116.62.133.126\",\"ts\":\"20230328134405\",\"uid\":\"2c922abb86e44e2c01870c9054bf7868\"}");
		String str = StringSort.doSign(jsonObject);
		System.out.println(MD5.md5(str.concat("&key=bca84f4393c78285e063785cfcca82d6")));
	}

	/**
	 * 检查地址
	 * @param phoneNum
	 * @return
	 */
	public Mobile checkMobile(String phoneNum){
		//匹配号码与运营商不符的直接返回错误
		Mobile mobile = mobileService.findPhone(phoneNum.substring(0, 7));
		if (mobile == null) {
			// 查询聚合数据
			net.sf.json.JSONObject city = HttpClient.httpGetJuhe(phoneNum);
			if (city.containsKey("resultcode") && city.getString("resultcode").equals("200")
					&& city.containsKey("result") && !city.getJSONObject("result").isNullObject()) {
				if (city != null && city.getJSONObject("result") != null) {
					// 更新新的电话号段到本地数据库中
					try {
						mobile = new Mobile();
						mobile.setCityCode(city.getJSONObject("result").getString("areacode"));
						mobile.setPhone(phoneNum.substring(0, 7));
						mobile.setProvince(city.getJSONObject("result").getString("province"));
						mobile.setCity(city.getJSONObject("result").getString("city"));
						mobile.setPostCode(city.getJSONObject("result").getString("zip"));
						mobile.setServiceProvider("中国" + city.getJSONObject("result").getString("company"));
						this.mobileService.saveMobile(mobile);
						return mobile;
					}catch (Exception e){
						e.printStackTrace();
						logger.info("异常号码:"+phoneNum);
					}
					return null;
				} else {
					return null;
				}
			}
		}
		return mobile;
	}

//	public static boolean orderFilter(String useruuid, String productid, String operator) {
//		if (CookieRedis.get("operator").equals(operator)
//				&& CookieRedis.get("productid").equals(productid)) {
//			return false;
//		}
//		return true;
//	}

	private String getRechargeMd5(com.alibaba.fastjson.JSONObject json, DownShopInfo shop) {
		return MD5.md5(StringSort.doSign(json).concat("&key="+shop.getDownkey()));
	}

	/***
	 * ip检查
	 * @param customerIp
	 * @param request
	 * @param isIp
	 * @return
	 */
	public boolean checkIp(String customerIp, HttpServletRequest request,boolean isIp) {
		if(isIp){
			boolean tempIp = false;
			String ips[] = customerIp.trim().split(",");
			for (String ip : ips) {
				if (ip.equals(IpUtil.getIp(request))) {
					tempIp = true;
					break;
				}
			}
			if (!tempIp) {
				logger.info("checkIp:" + IpUtil.getIp(request));
			}
			return tempIp;
		}
		return true;
	}

	/**
	 * 检查参数的合法性
	 *
	 * @param json
	 * @return
	 */
	private String chekcParameter(com.alibaba.fastjson.JSONObject json) {
		// if (json.getInt("rechargeNum") <= Config.amount) {
		// return ResultMessage.getFailt(ResultMessage.rechargeNumError);
		// }
//		if ( Double.valueOf(json.getString("amount")) <= Config.amount) {
//			return ResultMessage.getFailt(ResultMessage.faceValueError);
//		}

		// if (json.getInt("faceValue") * json.getInt("rechargeNum") !=
		// json.getInt("rechargeSum")) {
		// return ResultMessage.getFailt(ResultMessage.rechargeSumError);
		// }

		// 检查订单是否存在 如果存在则返回
		if (CookieRedis.get("orderOnOff").equals(Config.onOff)) {
			if (flowService.findByShopId(json.getString("orderId"),json.getString("uid")) != null) {
				return ResultMessage.getFailt(ResultMessage.shopNumError);
			}
		}
//		if (StringUtils.isBlank(json.getString("notify"))
//				&& json.getString("notify").startsWith("http")) {
//			return ResultMessage.getFailt(ResultMessage.notifyAddressError);
//		}
		return null;
	}

	@Path("queryOrder")
	@POST
	public synchronized String queryOrder(final String data, @Context HttpServletRequest request) {
		logger.info("down_queryOrder:" + data);
		String result = this.validationParameter(data, "oid", "ts", "uid", "sign");
		if (result == null) {
			JSONObject json = JSONObject.parseObject(data);
			DownShopInfo shop = shopService.findShopInfoByUuid(json.getString("uid"));
			if (shop != null) {
				if (checkIp(shop.getDownshopip(), request,true)) {
					if (json.getString("sign").equals(MD5.md5(StringSort.doSign(json).concat("&key="+shop.getDownkey())))) {
						DownRechargeFlow flow = this.flowService.findShopUUIDorder(json.getString("oid"),json.getString("uid"));
						if (flow != null) {
							JSONObject out = new JSONObject();
							// 状态 0 删除 1 充值中 2 充值成功 3充值失败 4成功后取消的订单 5订单达到 6退款成功
							// 7 退款失败 8失败后取消的订单 9 订单发送到上游失败
							out.put("orderNum", flow.getDownorderuuid());
							out.put("oid", flow.getDownreqid());
							out.put("createtime", DateUtils.toLongDate(flow.getCreatetime()));
							out.put("status", flow.getStatus());
							out.put("msg", flow.getRemark());
							logger.info("queryOrder:"+ out.toString());
							JSONObject jobOut = new JSONObject();
							jobOut.put("data",out);
							jobOut.put("code","1000");
							jobOut.put("message", "订单查询成功" );
							return jobOut.toJSONString();
						} else {
							return ResultMessage.getFailt(ResultMessage.orderNot);
						}
					}
					return ResultMessage.getFailt(ResultMessage.searchSignError);
				} else {
					return ResultMessage.getFailt(ResultMessage.shopNotexistErrorIP);
				}
			} else {
				return ResultMessage.getFailt(ResultMessage.shopNotexistErrorIP);
			}
		}
		return ResultMessage.getFailt(ResultMessage.orderStatusError);
	}


//	/**
//	 * 运营商查询接口
//	 *
//	 * @param data
//	 * @return
//	 */
//	@Path("queryMoblie")
//	@POST
//	public synchronized String queryMoblie(final String data, @Context HttpServletRequest request) {
//		logger.info("down_queryMoblie:" + data);
//		String result = this.validationParameter(data, "phoneNum", "ts", "uid", "sign");
//		if (result == null) {
//			JSONObject json = JSONObject.parseObject(data);
//			DownShopInfo shop = shopService.findShopInfoByUuid(json.getString("uid"));
//			if (shop != null) {
//				if (checkIp(shop.getDownshopip(), request,true)) {
//					if (json.getString("sign").equals(MD5.md5(StringSort.doSign(json).concat("&key="+shop.getDownkey())))) {
//						Mobile mobile = checkMobile(json.getString("phoneNum"));
//						if(mobile == null){
//							return ResultMessage.getFailt(ResultMessage.phoneNumErrorJingheng);
//						}
//						return ResultMessage.getSucceed(JSONObject.toJSONString(mobile));
//					}
//					return ResultMessage.getFailt(ResultMessage.searchSignError);
//				} else {
//					return ResultMessage.getFailt(ResultMessage.shopNotexistErrorIP);
//				}
//			} else {
//				return ResultMessage.getFailt(ResultMessage.shopNotexistErrorIP);
//			}
//		}
//		return ResultMessage.getFailt(ResultMessage.orderStatusError);
//	}
	/**
	 * 账户余额查询
	 *
	 * @param data
	 * @return
	 */
	@Path("searchAmount")
	@POST
	public String searchAmount(String data, @Context HttpServletRequest request) {
		logger.info("searchAmount:" + data);
		String result = this.validationParameter(data, "ts", "uid", "sign");
		if (result == null) {
			net.sf.json.JSONObject json = JsonUtils.converToJson(data);
			DownShopInfo shop = shopService.findShopInfoByUuid(json.getString("uid"));
			if (shop != null) {
				if (checkIp(shop.getDownshopip(), request,true)) {
					if (json.getString("sign").equals(getAmountMD5(json, shop))) {
						net.sf.json.JSONObject out = JsonUtils.getJSONOBJCT();
						out.put("balance", shop.getDownshopbalance());
						out.put("uid", shop.getDownshopuuid());
						JSONObject jobOut = new JSONObject();
						jobOut.put("data",out);
						jobOut.put("code","1000");
						jobOut.put("message", "余额查询成功" );
						return jobOut.toJSONString();
					}
					return ResultMessage.getFailt(ResultMessage.amountSignError);
				} else {
					return ResultMessage.getFailt(ResultMessage.shopNotexistErrorIP);
				}
			}
			return ResultMessage.getFailt(ResultMessage.amountParametersError);
		}
		return ResultMessage.getFailt(ResultMessage.amountParametersError);
	}

	private String getAmountMD5(net.sf.json.JSONObject json, DownShopInfo shop) {
		StringBuffer sb = null;
		sb = new StringBuffer();
		sb.append("uid=");
		sb.append(json.getString("uid"));
		sb.append("&ts=");
		sb.append(json.getString("ts"));
		sb.append("&key=");
		sb.append(shop.getDownkey());
		return MD5.md5(sb.toString());
	}

	// 下游回调
	@Path("call")
	@POST
	public String downCall(String data) {
		//hubeiRest.queryOrder(upOrder,shopInfo);
		//恢复数据
		for(int i =0 ; i < 400;i++){

		}
		return "0";
	}


}
